from aiogram import Router, types, F
from aiogram.filters import CommandStart, CommandObject, Command
from aiogram.fsm.context import FSMContext
from loguru import logger

from database import models
from tg_bot.filters.command_filter import WithDeepLink
from tg_bot.filters.user_filter import IsActive
from tg_bot.keyboards import inline, callback_factory as cf
from tg_bot.states.user import Menu

router = Router()
router.message.filter(IsActive())
router.callback_query.filter(IsActive())


@router.callback_query(cf.ActionCall.filter(
    F.action == 'menu'
))
async def menu_call_answer(call: types.CallbackQuery,
                           state: FSMContext):
    await menu_cmd_answer(call.message, state)


async def menu_cmd_answer(message: types.Message,
                          state: FSMContext):
    text = 'Выберите нужную категорию товаров: '
    data = await state.get_data()
    current_page = data.get('CategoryPaginator_page', 1)
    key = inline.CategoryPaginator(
        router,
        for_users=True,
        current_page=current_page,
        after_pagination_keyboards=[await inline.back('personal_account')]
    )
    try:
        await message.edit_text(text, reply_markup=key.as_markup())
    except Exception as e:
        logger.warning(e)
        await message.answer(text, reply_markup=key.as_markup())
    await state.set_state(Menu.category_choice)


@router.message(CommandStart(deep_link=True, magic=F.args.startswith('seat')), WithDeepLink())
async def menu_cmd_with_link(message: types.Message, state: FSMContext, command: CommandObject):
    await state.clear()
    seat_pk = int(command.args.replace('seat_', ''))
    seat: models.Seat = models.Seat.objects.get(pk=seat_pk)
    await state.update_data({'seat': seat})
    await menu_cmd_answer(message, state)


@router.message(Command(commands='menu'))
async def menu_cmd(message: types.Message, state: FSMContext):
    await menu_cmd_answer(message, state)


async def answer_product_menu(message: types.Message,
                              state: FSMContext):
    data = await state.get_data()
    category: models.Category = data.get('category')
    text = 'Выберите нужный товар: '
    data = await state.get_data()
    current_page = data.get('ProductPaginator_page', 1)
    key = inline.ProductPaginator(
        router,
        category=category,
        for_users=True,
        current_page=current_page,
        after_pagination_keyboards=[await inline.back('category_choice')]
    )
    if message.photo:
        await message.delete()
    try:
        await message.edit_text(text, reply_markup=key.as_markup())
    except Exception as e:
        logger.warning(e)
        await message.answer(text, reply_markup=key.as_markup())
    await state.set_state(Menu.product_choice)


@router.callback_query(cf.CategoryCall.filter(), Menu.category_choice)
async def category_choice(call: types.CallbackQuery,
                          state: FSMContext,
                          callback_data: cf.CategoryCall):
    category = models.Category.objects.get(pk=callback_data.pk)
    await state.update_data({'category': category})
    await answer_product_menu(call.message, state)


@router.callback_query(cf.BackCall.filter(
    F.to == 'category_choice'
), Menu.product_choice)
async def back_to_category_choice(call: types.CallbackQuery,
                                  state: FSMContext):
    await menu_cmd_answer(call.message, state)


@router.callback_query(cf.BackCall.filter(
    F.to == 'product_choice'
), Menu.product_choice)
async def back_to_product_choice(call: types.CallbackQuery,
                                 state: FSMContext):
    await answer_product_menu(call.message, state)


@router.callback_query(cf.ProductCall.filter(), Menu.product_choice)
async def product_choice(call: types.CallbackQuery,
                         state: FSMContext,
                         callback_data: cf.ProductCall):
    data = await state.get_data()
    products_count = data.get('products_count', 1)
    product = models.Product.objects.get(pk=callback_data.pk)
    text = product.product_info_text()
    key = await inline.concatenate_key(
        await inline.counter(products_count),
        await inline.order_keyboard(),
        await inline.back('product_choice')
    )
    if product.photo:
        await call.message.delete()
        await call.message.answer_photo(product.photo, caption=text, reply_markup=key)
    else:
        try:
            await call.message.edit_text(text, reply_markup=key)
        except Exception as e:
            logger.warning(e)
            await call.message.answer(text, reply_markup=key)
    await state.update_data({'product': product})


@router.callback_query(
    cf.ActionCall.filter(
        F.action.in_({'plus_value', 'minus_value'})
    ),
    Menu.product_choice
)
async def change_products_count(call: types.CallbackQuery,
                                state: FSMContext,
                                callback_data: cf.ActionCall):
    data = await state.get_data()
    product: models.Product = data.get('product')
    products_count = data.get('products_count', 1)
    products_count += 1 if callback_data.action == 'plus_value' else -1
    if products_count < 1:
        products_count = 1
    await state.update_data({'products_count': products_count})
    await product_choice(call, state, cf.ProductCall(pk=product.pk))


@router.callback_query(cf.ActionCall.filter(
    F.action == 'order_product'
), Menu.product_choice)
async def order_product(call: types.CallbackQuery,
                        state: FSMContext,
                        user: models.TgUser):
    return await call.answer('Заказ онлайн пока не работает...', show_alert=True)
    # data = await state.get_data()
    # product: models.Product = data.get('product')
    # seat: models.Seat | None = data.get('seat')
    # if seat:
    #     sales_main: models.SalesMain = seat.get_active_sales_main() or seat.open_seat()
    #     team: models.Team = models.WorkShift.get_active_team_worker()
    #     if not team:
    #         await call.answer('Кажется сотрудник не открыл смену...Напомните ему, пожалуйста!', show_alert=True)
    #     else:
    #         logger.debug(f'{sales_main=}\n{team=}\n{product=}\n{user=}')
    #         sales_main.add_sale(
    #             team=team,
    #             product=product,
    #             user=user
    #         )
    #         models.Product.check_and_update_products_status()
    #         await call.answer('Done!')
    # else:
    #     await call.answer('Для заказа отсканируйте QR-код на столе!', show_alert=True)
